const commentService = require('../services/comment.service');
const cacheService = require('../services/cache.service');
const { success, error } = require('../utils/response');

/**
 * 获取文章的评论列表
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 * @param {Function} next - 下一个中间件
 */
exports.getCommentsByPost = async (req, res, next) => {
  try {
    const { postId } = req.params;
    const { page = 1, limit = 10, status } = req.query;
    
    // 构建缓存键
    const cacheKey = `comments:post:${postId}:${page}:${limit}:${status || 'all'}`;
    
    // 尝试从缓存获取，如果没有则从数据库获取并缓存
    const comments = await cacheService.getOrSet(cacheKey, async () => {
      const options = { page, limit };
      
      // 如果是管理员请求，可以根据状态筛选
      if (req.user && req.user.role === 'admin' && status) {
        options.status = status;
      } else {
        // 非管理员只能看到已批准的评论
        options.status = 'approved';
      }
      
      return await commentService.findByPostId(postId, options);
    }, 300); // 缓存5分钟
    
    res.json(success(comments, '获取评论列表成功'));
  } catch (err) {
    next(err);
  }
};

/**
 * 获取单个评论
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 * @param {Function} next - 下一个中间件
 */
exports.getCommentById = async (req, res, next) => {
  try {
    const { id } = req.params;
    
    // 构建缓存键
    const cacheKey = `comments:${id}`;
    
    // 尝试从缓存获取，如果没有则从数据库获取并缓存
    const comment = await cacheService.getOrSet(cacheKey, async () => {
      return await commentService.findById(id);
    }, 600); // 缓存10分钟
    
    if (!comment) {
      return res.status(404).json(error('评论不存在', 404));
    }
    
    // 非管理员只能看到已批准的评论
    if (comment.status !== 'approved' && (!req.user || req.user.role !== 'admin')) {
      return res.status(403).json(error('无权访问此评论', 403));
    }
    
    res.json(success(comment, '获取评论成功'));
  } catch (err) {
    next(err);
  }
};

/**
 * 创建评论
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 * @param {Function} next - 下一个中间件
 */
exports.createComment = async (req, res, next) => {
  try {
    const commentData = req.body;
    
    // 设置评论作者为当前登录用户
    commentData.userId = req.user.id;
    
    // 如果用户是管理员，评论自动批准
    if (req.user.role === 'admin') {
      commentData.status = 'approved';
    }
    
    // 创建评论
    const comment = await commentService.create(commentData);
    
    // 清除相关缓存
    await cacheService.delByPattern(`comments:post:${commentData.postId}:*`);
    
    res.status(201).json(success(comment, '评论创建成功', 201));
  } catch (err) {
    next(err);
  }
};

/**
 * 更新评论状态（管理员功能）
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 * @param {Function} next - 下一个中间件
 */
exports.updateCommentStatus = async (req, res, next) => {
  try {
    const { id } = req.params;
    const { status } = req.body;
    
    // 检查评论是否存在
    const existingComment = await commentService.findById(id);
    
    if (!existingComment) {
      return res.status(404).json(error('评论不存在', 404));
    }
    
    // 更新评论状态
    await commentService.updateStatus(id, status);
    
    // 清除相关缓存
    await cacheService.del(`comments:${id}`);
    await cacheService.delByPattern(`comments:post:${existingComment.postId}:*`);
    
    // 获取更新后的评论
    const updatedComment = await commentService.findById(id);
    
    res.json(success(updatedComment, '评论状态更新成功'));
  } catch (err) {
    next(err);
  }
};

/**
 * 删除评论
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 * @param {Function} next - 下一个中间件
 */
exports.deleteComment = async (req, res, next) => {
  try {
    const { id } = req.params;
    
    // 检查评论是否存在
    const existingComment = await commentService.findById(id);
    
    if (!existingComment) {
      return res.status(404).json(error('评论不存在', 404));
    }
    
    // 检查权限：只有评论作者或管理员可以删除评论
    if (existingComment.userId !== req.user.id && req.user.role !== 'admin') {
      return res.status(403).json(error('无权删除此评论', 403));
    }
    
    // 删除评论
    await commentService.delete(id);
    
    // 清除相关缓存
    await cacheService.del(`comments:${id}`);
    await cacheService.delByPattern(`comments:post:${existingComment.postId}:*`);
    
    res.status(204).end();
  } catch (err) {
    next(err);
  }
};